/**************************************************************************
Copyright (C) 2008-2010 United States Government. All rights reserved. 

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
****************************************************************************/
package rage

import grails.test.*
import org.codehaus.groovy.grails.commons.ConfigurationHolder;

import rage.filters.Filter
import rage.filters.StringFilter

class FeedControllerTests extends ControllerUnitTestCase {
	protected void setUp() {
		super.setUp()

		//Set up mock for converterService
		def converterServiceMock = mockFor(ConverterService);
		converterServiceMock.demand.decodeParam(1..1) {String arg1 -> 
			return "http://localhost/site?this=a&that=b";
		};
		controller.converterService = converterServiceMock.createMock();
	}

	protected void tearDown() {
		super.tearDown()
	}

	void testKml() {
		def feedName = "feed";
		def feedDescription = "This Feed is the best!";

		//Set up mock for getService
		def getServiceMock = mockFor(GetService);
		getServiceMock.demand.getFeed(1..1) {String arg1, String arg2, String arg3 -> 
			return [responsecode: 200, content: "feed xml..."]
		};
		controller.getService = getServiceMock.createMock();

		//Set up mock for feedParserService
		def feedParserServiceMock = mockFor(FeedParserService);
		feedParserServiceMock.demand.parseFeed(2..2) {String arg1, List<Filter> arg2 -> 
			Feed feed = new Feed();
			feed.title = feedName;
			feed.description = feedDescription;
			return feed
		};
		controller.feedParserService = feedParserServiceMock.createMock();

		controller.params.url = "http://localhost:8080/feed.atom";
		controller.params.color = "ff0000";

		Map returnMap = controller.kml();

		assertNotNull("Controller did not return map", returnMap);
		Feed feed = returnMap.feedInstance;
		assertNotNull("Controller map does not contain expected model object: 'feedInstance'", feed);
		assertEquals(feedName, feed.title);
		assertEquals(feedDescription, feed.description);

		String color = returnMap.feedColor;
		assertNotNull("Controller map does not contain expected model object: 'feedColor'", color);
		assertEquals(controller.params.color, color);
	}

	void testKml_no_url_param() {

		controller.params.color = "ff0000";
		controller.kml();

		assertNotNull(controller.flash);
		assertNotNull(controller.flash.message);
	}

	void testKml_no_color_param() {

		def feedName = "feed";
		def feedDescription = "This Feed is the best!";

		//Set up mock configuration
		String defaultColor = "00ff00";
		def mockedConfig = new ConfigObject();
		mockedConfig.rage.default.marker.color = defaultColor;
		ConfigurationHolder.config = mockedConfig;

		//Set up mock for getService
		def getServiceMock = mockFor(GetService);
		getServiceMock.demand.getFeed(1..1) {String arg1, String arg2, String arg3 -> 
			return [responsecode: 200, content: "feed xml..."]
		};
		controller.getService = getServiceMock.createMock();

		//Set up mock for feedParserService
		def feedParserServiceMock = mockFor(FeedParserService);
		feedParserServiceMock.demand.parseFeed(2..2) {String arg1, List<Filter> arg2 -> 
			Feed feed = new Feed();
			feed.title = feedName;
			feed.description = feedDescription;
			return feed
		};
		controller.feedParserService = feedParserServiceMock.createMock();

		controller.params.url = "http://localhost:8080/feed.atom";

		Map returnMap = controller.kml();

		assertNotNull("Controller did not return map", returnMap);
		Feed feed = returnMap.feedInstance;
		assertNotNull("Controller map does not contain expected model object: 'feedInstance'", feed);
		assertEquals(feedName, feed.title);
		assertEquals(feedDescription, feed.description);

		String color = returnMap.feedColor;
		assertNotNull("Controller map does not contain expected model object: 'feedColor'", color);
		assertEquals(defaultColor, color);
	}

	void testKml_titleFilter_param() {
		def feedName = "feed";
		def feedDescription = "This Feed is the best!";

		//Set up mock for getService
		def getServiceMock = mockFor(GetService);
		getServiceMock.demand.getFeed(1..1) {String arg1, String arg2, String arg3 ->
			return [responsecode: 200, content: "feed xml..."]
		};
		controller.getService = getServiceMock.createMock();

		//Set up mock for feedParserService, verify title filter sent to caller
		def feedParserServiceMock = mockFor(FeedParserService);
		feedParserServiceMock.demand.parseFeed(2..2) {String arg1, List<Filter> arg2 ->
			assertNotNull("Filter list not expected to be null", arg2)
			assertEquals("Unexpected filter list size",
				1, arg2.size())
			StringFilter filter = arg2.get(0)
			assertNotNull("Filter not expected to be null", filter)
			assertEquals("Filter member field not set to expected value",
				StringFilter.Field.TITLE, filter.field)
			assertEquals("Filter member filterOperand not set to expected value",
				"hello", filter.filterOperand)
			assertEquals("Filter member operator not set to expected value",
				StringFilter.Operator.EQUALS, filter.operator)
		};
		controller.feedParserService = feedParserServiceMock.createMock();

		controller.params.url = "http://localhost:8080/feed.atom";
		controller.params.color = "ff0000";
		controller.params.title = "EQUALS_hello";

		Map returnMap = controller.kml();
	}
	
	void testKml_contentFilter_param() {
		def feedName = "feed";
		def feedDescription = "This Feed is the best!";

		//Set up mock for getService
		def getServiceMock = mockFor(GetService);
		getServiceMock.demand.getFeed(1..1) {String arg1, String arg2, String arg3 ->
			return [responsecode: 200, content: "feed xml..."]
		};
		controller.getService = getServiceMock.createMock();

		//Set up mock for feedParserService, verify title filter sent to caller
		def feedParserServiceMock = mockFor(FeedParserService);
		feedParserServiceMock.demand.parseFeed(2..2) {String arg1, List<Filter> arg2 ->
			assertNotNull("Filter list not expected to be null", arg2)
			assertEquals("Unexpected filter list size",
				1, arg2.size())
			StringFilter filter = arg2.get(0)
			assertNotNull("Filter not expected to be null", filter)
			assertEquals("Filter member field not set to expected value",
				StringFilter.Field.CONTENT, filter.field)
			assertEquals("Filter member filterOperand not set to expected value",
				"hello", filter.filterOperand)
			assertEquals("Filter member operator not set to expected value",
				StringFilter.Operator.EQUALS, filter.operator)
		};
		controller.feedParserService = feedParserServiceMock.createMock();

		controller.params.url = "http://localhost:8080/feed.atom";
		controller.params.color = "ff0000";
		controller.params.content = "EQUALS_hello";

		Map returnMap = controller.kml();
	}
	
	void testKml_numericalFilter_param() {
		def feedName = "feed";
		def feedDescription = "This Feed is the best!";

		//Set up mock for getService
		def getServiceMock = mockFor(GetService);
		getServiceMock.demand.getFeed(1..1) {String arg1, String arg2, String arg3 ->
			return [responsecode: 200, content: "feed xml..."]
		};
		controller.getService = getServiceMock.createMock();

		//Set up mock for feedParserService, verify title filter sent to caller
		def feedParserServiceMock = mockFor(FeedParserService);
		feedParserServiceMock.demand.parseFeed(2..2) {String arg1, List<Filter> arg2 ->
			assertNotNull("Filter list not expected to be null", arg2)
			assertEquals("Unexpected filter list size",
				1, arg2.size())
		};
		controller.feedParserService = feedParserServiceMock.createMock();

		controller.params.url = "http://localhost:8080/feed.atom";
		controller.params.color = "ff0000";
		controller.params.numerical = "TITLE_M_GREATERTHAN_3.0";

		Map returnMap = controller.kml();
	}
	
	void testKml_boundingBoxFilter_param() {
		def feedName = "feed";
		def feedDescription = "This Feed is the best!";

		//Set up mock for getService
		def getServiceMock = mockFor(GetService);
		getServiceMock.demand.getFeed(1..1) {String arg1, String arg2, String arg3 ->
			return [responsecode: 200, content: "feed xml..."]
		};
		controller.getService = getServiceMock.createMock();

		//Set up mock for feedParserService, verify title filter sent to caller
		def feedParserServiceMock = mockFor(FeedParserService);
		feedParserServiceMock.demand.parseFeed(2..2) {String arg1, List<Filter> arg2 ->
			assertNotNull("Filter list not expected to be null", arg2)
			assertEquals("Unexpected filter list size",
				1, arg2.size())
		};
		controller.feedParserService = feedParserServiceMock.createMock();

		controller.params.url = "http://localhost:8080/feed.atom";
		controller.params.color = "ff0000";
		controller.params.bbgeo = "-3.0,-2.0,-5.0,0.0";

		Map returnMap = controller.kml();
	}
	
	void testKml_get_error() {
		//Set up mock for getService
		def getServiceMock = mockFor(GetService);
		getServiceMock.demand.getFeed(1..1) {String arg1, String arg2, String arg3 -> 
			return [responsecode: 404, responsemessage: "not found"]
		};
		controller.getService = getServiceMock.createMock();

		controller.params.url = "http://localhost:8080/notfound";
		controller.params.color = "ff0000";

		controller.kml();

		assertNotNull(controller.flash);
		assertEquals("GET response[404]: not found", controller.flash.message);
	}
}
